package com.umfwechat.lightprogram.controller.merchant;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;

import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.umfwechat.common.code.RetCode;
import com.umfwechat.common.constant.CacheConsts;
import com.umfwechat.common.constant.CommonConsts;
import com.umfwechat.common.prop.UmfPropModel;
import com.umfwechat.lightprogram.vo.StoreAccountQueryVo;
import com.umfwechat.util.DateTimesUtil;
import com.umfwechat.util.EmailXmlUtil;
import com.umfwechat.util.PropertyUtil;
import com.umfwechat.util.RedisUtil;
import com.umfwechat.util.ReqMessageUtil;
import com.umfwechat.util.SettleDirFilter;
import com.umfwechat.util.TimePathUtil;
import com.umfwechat.util.ZipUtil;
import com.umfwechat.util.email.MailSenderInfo;
import com.umfwechat.util.email.SendMailUtil;

import com.umpay.sp.model.common.ReqMessage;
import com.umpay.sp.model.common.ResMessage;
import com.umpay.sp.model.saas.StoreInf;
import com.umpay.sp.model.settle.CollectSettleStat;
import com.umpay.sp.model.settle.SettleStat;

import com.umpay.sp.service.saas.remote.StoreInfServiceRemote;
import com.umpay.sp.service.settle.remote.SettleStatServiceRemote;
import com.umpay.sp.util.StringUtil;


import com.umpay.sp.xml.XmlData;

/**
 * 我的商户、昨日交易列表、月账单Controller
 * @author ChenFuLong
 * @version 2.0
 */
@Controller
@RequestMapping("/mystores")
public class Mystores {
	private static Logger logger = LoggerFactory.getLogger(Mystores.class);
	//获取最近四个月的起始时间
	static Map<Integer,String> startDateMap=new HashMap<Integer,String>();
	//获取最近四个月的结束时间
	static Map<Integer,String> endDateMap=new HashMap<Integer,String>();	
	@Resource
	private StoreInfServiceRemote storeInfServiceRemote;
	@Resource
	private SettleStatServiceRemote settleStatServiceRemote;
	private String yyyyMM = "yyyyMM";
	//邮件内容模板
	String templateEmailUrl = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties").getProperty("templateEmailUrl");
	String noFileTemplateEmailUrl = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties").getProperty("noFileTemplateEmailUrl");
	//文件打包路径
	String zipdownload = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties").getProperty("zipdownload");
	//日结算文件路径
	String excelPath = "";
	private int oneWeek = 7 * 24 * 60 * 60; //1周
	
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 我的商户 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	/**
	 * 我的商户三个拆线图
	 * @param req
	 * @param resp
	 * @return
	 */
	@RequestMapping(value = "/queryMerTradeAmountBystores", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject queryMerTradeAmountBystores(HttpServletRequest req, HttpServletResponse resp) {
		JSONObject result = new JSONObject();
		//查询店铺列表参数
		ReqMessage reqMsg=ReqMessageUtil.makeSpReq();
		ResMessage queryResMsg = new ResMessage();
		//查询金额笔数汇总参数
		ReqMessage querySumReqMsg=ReqMessageUtil.makeSpReq();
		ResMessage querySumResMsg = new ResMessage();
		//查询新增商户数参数
		ReqMessage queryCountReqMsg=ReqMessageUtil.makeSpReq();
		ResMessage queryCountResMsg = new ResMessage();
		//设置返回值接收参数
		List<Map> storeSumAmounts=new ArrayList<Map>();	//商户近四个月内每个月总交易额
		List<Map> storeSumNums=new ArrayList<Map>();	//商户近四个月内每个月总笔数
		List<Map> storeSumAdds=new ArrayList<Map>();	//商户近四个月内每个月商户新增数
		String storeSumAmount="";	//本月总交易额
		String storeSumNum="";	//本月总本数
		String storeSumAdd="";	//本月新增商家
		//获取查询参数：userId,agentId,
		String reqJSON=null;
		try {
			reqJSON = (String) req.getAttribute("_requestData");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		JSONObject param=JSONObject.fromObject(reqJSON);
		String userId=(String)param.get("userId");
		String agentId=(String)param.get("loginAgentId");
		if(StringUtil.isEmpty(userId)){
			result.put("retCode", "0001");
			result.put("retMsg", "用户名不能为空");
			return result;
		}
		if(StringUtil.isEmpty(agentId)){
			result.put("retCode", "0001");
			result.put("retMsg", "代理商不能为空");
			return result;
		}
		/*String userId="Cfl";
		String agentId="Y593075163";*/
		//判断是否是业务员,如果是将salesmanId放到参数中
		String agentIds ="";
		if(!userId.equals("admin")){
			reqMsg.put("salesmanId", userId);
			agentIds="'"+agentId+"'";
		}else{
			//如果是代理商就查询下级代理商编号，24工单
			//获取当前代理商的所有下级代理商信息
			logger.info("【调用查询当前代理商多级关系接口】");
		    Map<String, Object> params = ReqMessageUtil.makeReqCrmMap();
			params.put(CommonConsts.AGENTID, agentId);
			params.put(CommonConsts.RELTYPE, "2");
			Map<String, Object> crmResult = null;
			String retCode = "";
			Map<String, Object> agentMap  = null;
			try {
				XStream xstream = new XStream(new DomDriver());
				// URL配置文件取 --日志
	 			String url=UmfPropModel.INSTANCE.getPropValue("agent.crm.queryAgentRel");
				//调用受理注销用户标识接口---参数
	 			logger.info("【查询代理商多级关系接口】入参url：" + url);
				logger.info("【查询代理商多级关系接口】入参params：" + params);
				crmResult =  (Map<String, Object>) com.umfwechat.util.HttpUtil.getResObjPost(url, xstream, params);	
				logger.info("【查询代理商多级关系接口】出参：" + crmResult);				
				if(crmResult==null || crmResult.isEmpty()) {
					logger.info("==★====★★★★★★====★==查询代理商多级关系接口：请求CRM系统失败:查询代理商多级关系接口失败");				
					result.put(CommonConsts.RETCODE, "00434101");
					result.put(CommonConsts.RETMSG,"服务器异常，请稍后再试");	
					return result;
				}
				retCode = (String) crmResult.get(CommonConsts.RETCODE);
				if (!RetCode.SUCCESS.equals(retCode)){
					logger.info("查询代理商多级关系接口失败!");
					result.put(CommonConsts.RETCODE, "00434101");
					result.put(CommonConsts.RETMSG,"服务器异常，请稍后再试");	
					return result;
				}
				Map<String, Object> agentMetaMap =  (Map<String, Object>) crmResult.get("agentMetaMap");
				agentMap =  (Map<String, Object>) crmResult.get("agentMap");
				if( agentMetaMap.get("minLevel") == null ||  agentMetaMap.get("maxLevel") == null){
					logger.info("查询代理商多级关系接口获取参数失败!");
					result.put(CommonConsts.RETCODE, "00434101");
					result.put(CommonConsts.RETMSG,"服务器异常，请稍后再试");	
					return result;
				}
				Integer min = Integer.valueOf( agentMetaMap.get("minLevel").toString()) ;
				Integer max =  Integer.valueOf( agentMetaMap.get("maxLevel").toString()) ; 
				StringBuffer agens = new StringBuffer();//代理商集合
				for(int i = max;i<=min;i++){
					List s  = (List) agentMetaMap.get("agent["+i+"]List");
					for(int j =0 ;j<s.size();j++){
						agens.append("'"+s.get(j)+"',");
					}
				}
				agentIds = agens.toString().substring(0,agens.toString().length()-1);//代理商集合
			} catch (Exception e) {
				logger.error("【调用查询代理商多级关系接口失败!】",e);
				result.put(CommonConsts.RETCODE, "00434101");
				result.put(CommonConsts.RETMSG,"服务器异常，请稍后再试");	
				return result;
			}
		}
		reqMsg.put("agentIds",agentIds);
		reqMsg.put("registerProcsStates","'06','07','08','09'");
		//获取近四个月的当天日期集合
		ArrayList monthlist=new ArrayList();
		for(int i=0;i<4;i++){
			Calendar cal=Calendar.getInstance();
			cal.add(Calendar.MONTH,-i);
			monthlist.add(cal.getTime());
		}
		//获取当前月
		Calendar c=Calendar.getInstance();
		int currentMonth=c.get(c.MONTH)+1;
		//获取最近四个月的第一天,最后一天并放到Map中
		for(int i=0;i<monthlist.size();i++){
			 getLastDayOfMonth((Date)monthlist.get(i));
		}
		//调用查询接口
		queryResMsg=storeInfServiceRemote.getStoreInfList(reqMsg);
		//成功查询业务员所属商铺列表
		if(queryResMsg.getRetCode().equals("0000")){
			if(Integer.parseInt(queryResMsg.getResMap().get("totalSize").toString())>0){
				//循环近四个月
				for(int i=0;i<monthlist.size();i++){
					Date date=(Date)monthlist.get(i);
					int month=date.getMonth()+1;
					if(month==currentMonth){
						endDateMap.put(month, DateTimesUtil.date8(new Date()));
					}
					//获取商铺列表
					List<StoreInf> storeInfList=(List<StoreInf>)queryResMsg.getResMap().get("storeInfList");
					int length=storeInfList.size();
					StringBuilder sb=new StringBuilder();
					for(int j=0;j<length;j++){
						sb.append("'");
						sb.append(storeInfList.get(j).getStoreId());
						sb.append("'");
						sb.append(",");
					}
					String QueryMonth=startDateMap.get(month).substring(0, 4)+"-"+startDateMap.get(month).substring(4,6);
					//设置汇总查询的参数
					querySumReqMsg.put(XmlData.START_DATE, startDateMap.get(month));
					querySumReqMsg.put(XmlData.END_DATE,endDateMap.get(month));
					querySumReqMsg.put(XmlData.MER_ID_S,sb.toString().substring(0,sb.toString().length()-1));
					//查询交易金额及笔数
					querySumResMsg=settleStatServiceRemote.collectSettleStatsByMerIdAndDate(querySumReqMsg);					
					Map<String,String> storeSumAmountsMap=new HashMap<String,String>();
					Map<String,String> storeSumNumsMap=new HashMap<String,String>();
					String sumAdd="";
					String amountAdd="";
					String count="";
					if(querySumResMsg.getRetCode().equals("0000")){
						//将金额、笔数汇总放到Map中
						List<CollectSettleStat> collectSettleStatList=
								(List<CollectSettleStat>)querySumResMsg.getValue(XmlData.COLLECT_SETTLE_STAT_LIST);
						 BigDecimal loanNums=new BigDecimal("0");
						 BigDecimal sums=new BigDecimal("0");
						 
						for(int j=0;j<collectSettleStatList.size();j++){
							 BigDecimal  amount=new BigDecimal(collectSettleStatList.get(j).getAmount());
							/* BigDecimal comamt=new BigDecimal(collectSettleStatList.get(j).getComamt());*/
							 BigDecimal loanNum=new BigDecimal(collectSettleStatList.get(j).getLoanNum());
							 loanNums = loanNums.add(loanNum);
							 sums = sums.add(amount);
 						}
						sumAdd=sums.toString()==""?"0":sums.toString();
					    amountAdd= loanNums.toString()==""?"0": loanNums.toString();
						storeSumAmountsMap.put("amount",sumAdd);
						storeSumAmountsMap.put("date",QueryMonth);
						storeSumNumsMap.put("num",amountAdd);
						storeSumNumsMap.put("date", QueryMonth);
					}else{
						result.put("retCode", "0001");
						result.put("retMsg", querySumResMsg.getRetMsg());
						return result;
					}
					storeSumAmounts.add(storeSumAmountsMap);
					storeSumNums.add(storeSumNumsMap);
					//设置查询新增商户数的参数
					String intimeStart=startDateMap.get(month).substring(0, 4)+
							"-"+startDateMap.get(month).substring(4, 6)+
							 "-"+startDateMap.get(month).substring(6);
					String intimeEnd=endDateMap.get(month).substring(0, 4)+
							"-"+endDateMap.get(month).substring(4, 6)+
							 "-"+endDateMap.get(month).substring(6);
					
					if(!userId.equals("admin")){
						queryCountReqMsg.put("salesmanId",userId);
					}
					queryCountReqMsg.put("agentIds",agentIds);
					queryCountReqMsg.put("intimeStart", intimeStart);
					queryCountReqMsg.put("intimeEnd", intimeEnd);
					queryCountReqMsg.put("registerProcsStates","'06','07','08','09'" );
					queryCountResMsg=storeInfServiceRemote.getStoreInfCount(queryCountReqMsg);
					Map<String,String> storeSumAddsMap=new HashMap<String,String>();
					
					if(queryCountResMsg.getRetCode().equals("0000")){
						count=queryCountResMsg.getValue(XmlData.STORE_INF_COUNT).toString();
						if(StringUtil.isEmpty(count)){
							count="0";
						}
						storeSumAddsMap.put("date", QueryMonth);
						storeSumAddsMap.put("num",count);
					}else{
						result.put("retCode", "0001");
						result.put("retMsg",queryCountResMsg.getRetMsg());
						return result;
					}
					//获取当月汇总
					if(month==currentMonth){
						storeSumAmount=	sumAdd;
						storeSumNum=amountAdd;
						storeSumAdd=count;
					}
					result.put("storeSumAmount", storeSumAmount);
					result.put("storeSumNum",storeSumNum);
					result.put("storeSumAdd",storeSumAdd);
					storeSumAdds.add(storeSumAddsMap);
					result.put("retCode",RetCode.SUCCESS);
					result.put("retMsg","获取信息成功！");
					result.put("storeSumAmounts", storeSumAmounts);
					
					result.put("storeSumAdds",storeSumAdds);
					result.put("storeSumNums",storeSumNums);
				}
				
			}else{
				//商铺列表为空
				result.put("retCode","0010");
				result.put("retMsg","商铺列表为空");
			}
			
		}else{
			//查询商铺失败
			result.put("retCode","0001");
			result.put("retMsg",queryResMsg.getRetMsg());
		}
		return result;	
	}
	//根据当前时间获取本月最大天数及最小天数
	public   static   void   getLastDayOfMonth(Date   sDate1)   {
	    Calendar   cDay1   =   Calendar.getInstance();  
	    cDay1.setTime(sDate1);  
	    final   int   lastDay   =   cDay1.getActualMaximum(cDay1.DAY_OF_MONTH);  
	    Date   lastDate   =   cDay1.getTime();  
	    lastDate.setDate(lastDay); 
	    endDateMap.put(sDate1.getMonth()+1,DateTimesUtil.date8(lastDate));
	    final   int   firstDay   =   cDay1.getMinimum(cDay1.DAY_OF_MONTH);  
	    Date   firstDate   =   cDay1.getTime();  
	    firstDate.setDate(firstDay); 
	    startDateMap.put(sDate1.getMonth()+1,DateTimesUtil.date8(firstDate));
	}
	
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 查询昨日交易列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	/**
	 * 我的商户--点任意一个折线图--昨日交易列表
	 * @param req
	 * @param resp
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/queryYesterdayMerTradeAmountBystores", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject queryYesterdayMerTradeAmountBystores(HttpServletRequest req, HttpServletResponse resp) {
		JSONObject result=new JSONObject();
		
		//查询店铺列表参数
		ReqMessage reqMsg=ReqMessageUtil.makeSpReq();
		ResMessage queryResMsg = new ResMessage();
		
		//获取查询参数：userId,agentId,
		String reqJSON=null;
		try {
			reqJSON = (String) req.getAttribute("_requestData");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		JSONObject param=JSONObject.fromObject(reqJSON);
		String userId=(String)param.get("loginUserId");
		String agentId=(String)param.get("loginAgentId");
		String order = (String) param.get("order");
		String flag = (String) param.get("flag");
		String pageNo=(String)param.get("pageNo");
		String pageSize=(String)param.get("pageSize");
		if(StringUtil.isEmpty(pageNo)){
			pageNo="1";
		}
		if(StringUtil.isEmpty(pageSize)){
			pageSize="20";
		}
		Integer startNo = Integer.valueOf(pageSize)*(Integer.valueOf(pageNo)-1);	//计算开始行数
		Integer endNo = Integer.valueOf(pageSize)*Integer.valueOf(pageNo);	//计算结束行数
		if(StringUtil.isEmpty(userId)){
			result.put("retCode", "0001");
			result.put("retMsg", "用户名不能为空");
			return result;
		}
		if(StringUtil.isEmpty(agentId)){
			result.put("retCode", "0001");
			result.put("retMsg", "代理商账号不能为空");
			return result;
		}
		if(!userId.equals("admin")){
			reqMsg.put("salesmanId", userId);
		}
		reqMsg.put("agentId",agentId);
		reqMsg.put("registerProcsStates","'06','07','08','09'");
		//设置昨天的日期
		Calendar cal=Calendar.getInstance();
		cal.add(Calendar.DATE, -1); 
		String yesterDay=DateTimesUtil.date8(cal.getTime());
		//调用查询接口
		logger.info("----#---------#--获取自助部署列表，请求参数：--#---------#--" + reqMsg);
		queryResMsg = storeInfServiceRemote.getStoreInfList(reqMsg);
		logger.info("----#---------#--获取自助部署列表，返回参数：--#---------#--" + queryResMsg);
		if(queryResMsg.getRetCode().equals("0000")){
			if(Integer.parseInt(queryResMsg.getResMap().get("totalSize").toString())>0){
				List<StoreInf> storeInfList=(List<StoreInf>)queryResMsg.getResMap().get(XmlData.STORE_INF_LIST);	//获取商铺列表
				StringBuilder sb=new StringBuilder();
				for(int i=0;i<storeInfList.size();i++){
					sb.append("'");
					sb.append(storeInfList.get(i).getStoreId());
					sb.append("'");
					sb.append(",");
				}
				//查询金额笔数汇总参数
				ReqMessage querySumReqMsg=ReqMessageUtil.makeSpReq();
				ResMessage querySumResMsg = new ResMessage();
				//设置汇总查询的参数
				String orderName = "MERID";	//默认按部署时间排序（店铺编号越大，部署时间越晚）
				if(order.equals("1")){	//交易量
					orderName = "AMOUNT";
				}else if (order.equals("2")) {	//交易笔数
					orderName = "LOANNUM";
				}
				if (flag.equals("1")) {	//升序
					orderName = orderName + " " + "ASC";
				}else if (flag.equals("2")) {	//降序
					orderName = orderName + " " + "DESC";
				}
				querySumReqMsg.put("yesterday",yesterDay);
				//querySumReqMsg.put("startNo",startNo.toString());
				//querySumReqMsg.put("endNo",endNo.toString());
				querySumReqMsg.put("orderName",orderName);
				querySumReqMsg.put("merIds",sb.toString().substring(0,sb.toString().length()-1));
				//查询统计
				logger.info("----#---------#--获取昨日交易列表，请求参数：--#---------#--" + querySumReqMsg);
				querySumResMsg=settleStatServiceRemote.collectSettleStatsByMerIdYesterday(querySumReqMsg);
				logger.info("----#---------#--获取昨日交易列表，返回参数：--#---------#--" + querySumResMsg);
				if(querySumResMsg.getRetCode().equals("0000")){
					List<CollectSettleStat> collectSettleStatList = (List<CollectSettleStat>)querySumResMsg.getValue("collectSettleStatList");
					List<StoreAccountQueryVo> storeList=new ArrayList<StoreAccountQueryVo>();
					
					/**
					 * 获取T_SETTLE_STAT表中所有统计的数据
					 */
					for (int i = 0; i < collectSettleStatList.size(); i++) {
						for (int j = 0; j < storeInfList.size(); j++) {
							StoreInf storInf=storeInfList.get(j);
							if (collectSettleStatList.get(i).getMerId().equals(storInf.getStoreId())) {
								StoreAccountQueryVo saqVo=new StoreAccountQueryVo();
								saqVo.setStoreId(storInf.getStoreId());
								saqVo.setStoreName(storInf.getStoreShortName());
								saqVo.setPosReportId(storInf.getPosReportId());
								saqVo.setCreateDate(DateTimesUtil.date10(storInf.getIntime()));
								saqVo.setSumAmount(collectSettleStatList.get(i).getAmount());
								saqVo.setSumNum(collectSettleStatList.get(i).getLoanNum());
								storeInfList.remove(j);
								storeList.add(saqVo);
							}
						}
					}
					
					/**
					 * 没有数据的店铺，设置为0，并且补充到集合中
					 */
					for (int i = 0; i < storeInfList.size(); i++) {
						StoreInf storInf=storeInfList.get(i);
						StoreAccountQueryVo saqVo=new StoreAccountQueryVo();
						saqVo.setStoreId(storInf.getStoreId());
						saqVo.setStoreName(storInf.getStoreShortName());
						saqVo.setPosReportId(storInf.getPosReportId());
						saqVo.setCreateDate(DateTimesUtil.date10(storInf.getIntime()));
						saqVo.setSumAmount("0");
						saqVo.setSumNum("0");
						storeList.add(saqVo);
					}
					
					/**
					 * 对要返回的数据进行大排序
					 */
					if (orderName.contains("MERID")) {	//如果是MERID，则按部署时间排序
						if(flag.equals("1")){
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
									try {
										Date dt1 = format.parse(o1.getCreateDate());
										Date dt2 = format.parse(o2.getCreateDate());
										if (dt1.getTime() > dt2.getTime()) {
											return 1;
										} else if (dt1.getTime() < dt2.getTime()) {
											return -1;
										} else {
											return 0;
										}
									} catch (Exception e) {
										e.printStackTrace();
									}
									return 0;
								}
							});
						}else {
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
									try {
										Date dt1 = format.parse(o1.getCreateDate());
										Date dt2 = format.parse(o2.getCreateDate());
										if (dt1.getTime() < dt2.getTime()) {
											return 1;
										} else if (dt1.getTime() > dt2.getTime()) {
											return -1;
										} else {
											return 0;
										}
									} catch (Exception e) {
										e.printStackTrace();
									}
									return 0;
								}
							});
						}
					}else if (orderName.contains("AMOUNT")) {	//如果是AMOUNT，则按交易量排序
						if (flag.equals("1")) {
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									return o1.getSumAmount().compareTo(o2.getSumAmount());
								}
							});
						}else {
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									return o2.getSumAmount().compareTo(o1.getSumAmount());
								}
							});
						}
					}else if (orderName.contains("LOANNUM")) {	//如果是LOANNUM，则按交易笔数排序
						if (flag.equals("1")) {
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									return o1.getSumNum().compareTo(o2.getSumNum());
								}
							});
						}else {
							Collections.sort(storeList, new Comparator<StoreAccountQueryVo>() {
								@Override
								public int compare(StoreAccountQueryVo o1, StoreAccountQueryVo o2) {
									return o2.getSumNum().compareTo(o1.getSumNum());
								}
							});
						}
					}
					
					/**
					 * 对排序好的数据进行分页
					 */
					List<StoreAccountQueryVo> list=new ArrayList<StoreAccountQueryVo>();
					for (int i = startNo; i < storeList.size(); i++) {
						if (i == endNo) {
							break;
						}
						list.add(storeList.get(i));
					}
					
					
					result.put("retCode",querySumResMsg.getRetCode());
					result.put("retMsg",querySumResMsg.getRetMsg());
					result.put("storeList", list);
				}else{
					result.put("retCode", "0001");
					result.put("retMsg",querySumResMsg.getRetMsg());
					
				}
			}else{
				//商铺列表为0
				result.put("retCode", "0010");
				result.put("retMsg","商铺列表为空");
			}
		}else{
			result.put("retCode", "0001");
			result.put("retMsg",queryResMsg.getRetMsg());
		}
		return result;
	}


/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 月账单 + + + + + + + + + + + + + + + + + + + + + + + + + + + */	
	/**
	 * 我的商户--点任意拆线图--点任意店铺--月账单
	 * @param session
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value="/queryCurstoreTradeByMonth", produces="application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject getMonthBillList(HttpSession session,HttpServletRequest request, HttpServletResponse response){
		logger.info("商户月账单列表查询接口 开始");
		
		String reqJSON=null;
		try {
			reqJSON = (String) request.getAttribute("_requestData");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		JSONObject param=JSONObject.fromObject(reqJSON);
		String storeId =(String) param.get("storeId");
		String pageSizeStr = (String)param.get("pageSize");
		String currentPageStr =(String) param.get("pageNo");
		
		JSONObject resultJson = new JSONObject();
		List<String> resultList = new ArrayList<String>();
		
		if(StringUtil.isEmpty(storeId)){
			logger.info("店铺编号不能为空！"); 
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "店铺编号不能为空！");
			return resultJson;
		}
		if(StringUtil.isEmpty(pageSizeStr) 
				|| Integer.parseInt(pageSizeStr) == 0){
			logger.info("每页条数必须大于0！");
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "每页条数必须大于0！");
			return resultJson;
		}
		if(StringUtil.isEmpty(currentPageStr) 
				|| Integer.parseInt(currentPageStr) == 0){
			logger.info("当前页数必须大于0！");
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "当前页数必须大于0！");
			return resultJson;
		}
		
		try{
			int currentPage = Integer.parseInt(currentPageStr);
			int pageSize = Integer.parseInt(pageSizeStr);
			
			//当前时间
			Calendar calendar = Calendar.getInstance();
			String currentDateStr =  DateTimesUtil.date8(calendar.getTime());

			//最近1年
			Calendar preYearCalendar = Calendar.getInstance();
			preYearCalendar.add(Calendar.YEAR, -1);
			preYearCalendar.add(Calendar.MONTH, 1);
			preYearCalendar.set(Calendar.DATE, 1);
			String minDateStr = DateTimesUtil.date8(preYearCalendar.getTime());
			
			String currentStr = "";
			String endSettleYm = "";
			Calendar calendarYm = Calendar.getInstance();
			String calendarYmStr = DateTimesUtil.formatDate(calendarYm.getTime(), yyyyMM);
			int loopCnt = 0;
			if(currentPage == 1){//当月账单，调用结算查询接口
				calendar.set(Calendar.DATE, 1);
				String currFirstDate =  DateTimesUtil.date8(calendar.getTime());
				
				//结算查询
		        Map<String, Object> qryMap = new HashMap<String, Object>();
				qryMap.put("merId", storeId);//商户编号
				qryMap.put("endDate", currentDateStr);//结束时间
				qryMap.put("startDate", currFirstDate);//开始时间
				qryMap.put("dealState", "2"); //处理完成
				logger.info("结算查询 qryMap=" + qryMap);
				List<SettleStat> settleStatList = settleStatServiceRemote.querySettleStats(qryMap);
				
				Map<String, Object> dataMap = new HashMap<String, Object>();
				dataMap.put("date", currentDateStr.substring(0, 4) + "-" + currentDateStr.substring(4, 6));
				if(settleStatList == null || settleStatList.size() == 0){
					dataMap.put("amount", 0 + "");
				}else{
					//按月统计
					Long amount = 0L;
					for(SettleStat settleStat : settleStatList){
						amount = amount + settleStat.getAmount();
					}
					//dataMap.put("amount", AmountUtil.Cent2Dollar2(amount));//分转元
					dataMap.put("amount", amount + "");
				}
				currentStr = JSONObject.fromObject(dataMap).toString();
				resultList.add(currentStr);
				loopCnt = pageSize - 1;
				endSettleYm = addMonths(calendarYmStr, -1);
				calendarYm.add(Calendar.MONTH, -1);
			}else{
				loopCnt = pageSize;
				int months = -(currentPage-1) * loopCnt;
				endSettleYm = addMonths(calendarYmStr, months);
				calendarYm.add(Calendar.MONTH, months);
			}
			
			//查询缓存
			boolean redisNotExsitFlg = false;
			//查看
			boolean maxViewFlg = false;
			boolean hasNextData = false;
			
			for(int i=0; i<loopCnt; i++){
				String yearMonth = addMonths(endSettleYm, -i);
				if(yearMonth.compareTo(minDateStr.substring(0,6)) < 0){
					maxViewFlg = true;
					break;
				}
				String redisKey = "SAAS_XCX888" + CacheConsts.MONTHBILL + storeId + yearMonth;
				String redisVal = RedisUtil.get(redisKey);
				if(StringUtil.isEmpty(redisVal)){ //缓存中不存在
					redisNotExsitFlg = true;
					break;
				}
				//订单信息添加到日统计列表
				logger.info("----#---------#--从缓存中获取当前账单--#---------#--" + redisVal);
				resultList.add(redisVal);
			}
			
			//最多能看 或者 缓存存在
	        if(maxViewFlg || !redisNotExsitFlg){
	        	logger.info("获取月账单成功！");
	        	resultJson.put("retCode", RetCode.SUCCESS);
	        	resultJson.put("retMsg", "获取月账单成功！");
	        	resultJson.put("hasNextData", hasNextData);
	        	resultJson.put("tradeList", resultList);
	    		return resultJson;
	        }
	        
	        //初期化列表
	        resultList = new ArrayList<String>();
			if(!StringUtil.isEmpty(currentStr)){
				resultList.add(currentStr);	
			}
			
	        //结算查询
			String endSettleDate = endSettleYm + getDaysOfMonth(endSettleYm);
			String startSettleDate = addMonths(endSettleYm, -loopCnt + 1) + "01";
	        Map<String, Object> qryMap = new HashMap<String, Object>();
			qryMap.put("merId", storeId);//商户编号
			qryMap.put("endDate", endSettleDate);//结束时间
			qryMap.put("startDate", startSettleDate);//开始时间
			qryMap.put("dealState", "2"); //处理完成
			logger.info("结算查询 qryMap=" + qryMap);
			List<SettleStat> settleStatList = settleStatServiceRemote.querySettleStats(qryMap);
			
			//下一页是否有数据
			Map<String, Object> qryMapNext = new HashMap<String, Object>();
			qryMapNext.put("merId", storeId);//商户编号
			qryMapNext.put("endDate", addMonths(startSettleDate, -1));//结束时间
			qryMapNext.put("startDate", minDateStr.substring(0,6));//开始时间
			qryMapNext.put("dealState", "2"); //处理完成
			logger.info("结算查询(下一页是否有数据) qryMapNext=" + qryMapNext);
			List<SettleStat> settleStatListNext = settleStatServiceRemote.querySettleStats(qryMapNext);
			
			if(settleStatListNext != null && settleStatListNext.size() > 0){
				hasNextData = true;
			}
			//按月统计
			List<SettleStat> newSettleStatList = new ArrayList<SettleStat>();
			if(settleStatList != null && settleStatList.size()>0){
				for(SettleStat settleStat : settleStatList){
					boolean isOld = false;
					String settleStatYm = settleStat.getSettleDate().substring(0,6);
					for(SettleStat newSettleStat : newSettleStatList){
						//相同年月
						if(settleStatYm.equals(newSettleStat.getSettleDate().substring(0,6))){
							//结算金额
							newSettleStat.setAmount(newSettleStat.getAmount() + settleStat.getAmount());
							isOld = true;
						}
					}
					if(!isOld){
						newSettleStatList.add(settleStat);
					}
				}
			}
			
			//编辑输出列表
			if(newSettleStatList.size() > 0 || hasNextData){
				for(int i=0; i<loopCnt; i++){
					String successAmt = "0";
					String yearMonth = addMonths(endSettleYm, -i);
					for(SettleStat settleStat : newSettleStatList){
						if(yearMonth.equals(settleStat.getSettleDate().substring(0,6))){
							//successAmt = AmountUtil.Cent2Dollar2(settleStat.getAmount());//分转元
							successAmt = String.valueOf(settleStat.getAmount());
							break;
						}
					}
					Map<String, Object> dataMap = new HashMap<String, Object>();
					dataMap.put("date", yearMonth.substring(0, 4) + "-" + yearMonth.substring(4, 6));
					dataMap.put("amount", successAmt);
					String dataStr = JSONObject.fromObject(dataMap).toString();
					resultList.add(dataStr);
					//添加到缓存
					String redisKey = "SAAS_XCX888" + CacheConsts.MONTHBILL + storeId + yearMonth;
					RedisUtil.set(redisKey, oneWeek, dataStr);
				}
			}
			
			logger.info("获取月账单成功！");
			resultJson.put("retCode", RetCode.SUCCESS);
			resultJson.put("retMsg", "获取月账单成功！");
			resultJson.put("hasNextData", hasNextData);
			resultJson.put("tradeList", resultList);
			return resultJson;
			
		} catch (Exception e) {
			logger.info("获取月账单失败",e);
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取月账单失败");
			return resultJson;
		}
	}
	/**
	 * desc:发送月账单邮件
	 * 
	 * @param reqMessage
	 * @return ResMessage
	 * @throws 
	 * 	 */
	@RequestMapping(value="/sendBillEmail", produces="application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject sendBillEmail(HttpSession session,HttpServletRequest request, HttpServletResponse response){
		logger.info("发送月账单邮件开始");
		String reqJSON=null;
		try {
			reqJSON = (String) request.getAttribute("_requestData");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		JSONObject param=JSONObject.fromObject(reqJSON);
		final String storeId = (String)param.get("storeId");
		final String email = (String)param.get("email");
		String month =(String)param.get("billMonth");
		final String billMonth = month.substring(0, 4) + month.substring(5, 7);
		
		JSONObject resultJson = new JSONObject();
		//店铺部署详情查询
		ReqMessage reqMessage = ReqMessageUtil.makeSpReq();
		reqMessage.put(XmlData.STORE_ID, storeId);
		ResMessage resMessage = storeInfServiceRemote.getStoreInfByPri(reqMessage);
		StoreInf storeInf = (StoreInf)resMessage.getValue(XmlData.STORE_INF);
		if(!resMessage.getRetCode().equals(RetCode.SUCCESS) || storeInf == null){
			logger.info("店铺部署详情查询失败！");
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "店铺部署详情查询失败");
			return resultJson;
		}
		
		final String payeeName = storeInf.getPayeeName();	//收款人姓名
		final String merId = storeInf.getMerId();	//主商户号
		
		// 新启动一个线程 发送邮件
		new Thread() {
			public void run(){
				logger.info("查找结算文件开始！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
				//获取结算日期集合
				List<String> settleDateList = getSettleDateList(billMonth);
				try {
					//文件路径集合
					List<String> dayFilePathList = getBatchFilePath(merId, settleDateList);
					boolean notExistsBoolean = true;
					if(dayFilePathList != null && dayFilePathList.size() > 0){
						for (String pathNameTmp : dayFilePathList) {
							File file = new File(pathNameTmp);
							if(file.exists()){
								notExistsBoolean = false;
							}
							file=null;
						}
					}
					if(notExistsBoolean){
						sendMail(noFileTemplateEmailUrl, email, payeeName, merId, billMonth, null);
						logger.info("结算文件还未生成邮件已发送，请查收！");
						return;
					}
					logger.info("查找结算文件结束！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
					
					logger.info("结算文件打包开始！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
					//文件打包
					File file = new File(zipdownload);//打包地址
					if (!file.exists()){
						file.mkdirs();
					}
					final String zipFileName = payeeName + "_" + merId + "_" + billMonth + ".zip";
					File zipFile = new File(zipdownload, File.separatorChar + zipFileName);
					//打包文件
					ZipUtil.zip(zipFile, dayFilePathList);
					logger.info("结算文件打包结束！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
					zipFile = new File(zipdownload+File.separatorChar+zipFileName);
					if (zipFile.exists()) {
						List<File> fileList = new ArrayList<File>();
						fileList.add(zipFile);
						//发邮件
						sendMail(templateEmailUrl, email, payeeName, merId, billMonth, fileList);
						logger.info("对账单邮件已发送，请查收！");
					}
				} catch (Exception e) {
					logger.error("发送邮件失败！" + e);
				}
			};
		}.start();
		logger.info("对账邮件将在3-5分钟后送达，请注意查收！");
		resultJson.put("retCode", "0001");
		resultJson.put("retMsg", "对账邮件将在3-5分钟后送达，请注意查收！");
		return resultJson;
	}
	
	/**
	 * 发送邮件
	 * 
	 * @param templateUrl 邮件内容模板
	 * @param email 收件邮箱
	 * @param storeShortName 收款人姓名
	 * @param storeId 主商户号
	 * @param billMonth 账单年月
	 * @param fileList 附件
	 */
	private void sendMail(String templateUrl, String email, String payeeName, String merId, String billMonth, List<File> fileList){
		logger.info("发送邮件开始！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
		Calendar calendar = Calendar.getInstance();
		String currentDate = DateTimesUtil.date8(calendar.getTime());
		//发邮件
		String mailto = email;
		String subject = payeeName + "_" + merId + "_" + billMonth + "电子对账单"; //收款人姓名_主商户号_账单月份电子对账单
		//邮件内容			
		Map<String, String> map = new HashMap<String, String>();
		map.put("payeeName", payeeName);
		map.put("merId", merId);
		map.put("billMonth", billMonth);
		map.put("YYYY", currentDate.substring(0,4));
		map.put("MM", currentDate.substring(4,6));
		map.put("DD", currentDate.substring(6,8));
		MailSenderInfo mailSenderInfo = new MailSenderInfo();
		mailSenderInfo.setToAddress(email);
		EmailXmlUtil.emailXmlRead(templateUrl, mailSenderInfo, map);
		String mailContent = mailSenderInfo.getContent();
		for (String s : map.keySet()) {
			mailContent = mailContent.replaceAll(s, map.get(s));
		}
		//发邮件
		if(fileList == null){
			SendMailUtil.sendMail(mailto, subject, mailContent);
		}else{
			SendMailUtil.sendMail(mailto, subject, mailContent, fileList);
		}
		logger.info("发送邮件结束！" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
	}
	
	
	/**
	 * 日期加减月数
	 * 
	 * @param yearMonth 年月
	 * @param months 月数
	 * @return
	 */
	private String addMonths(String yearMonth, int months){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, Integer.parseInt(yearMonth.substring(0, 4)));
		calendar.set(Calendar.MONTH, Integer.parseInt(yearMonth.substring(4, 6))-1);
		calendar.set(Calendar.DATE, 1);
		calendar.add(Calendar.MONTH, months);
        return DateTimesUtil.date8(calendar.getTime()).substring(0,6);
	}

	/**
	 * 获得某月的天数
	 * 
	 * @param yearMonth 年月
	 * @return
	 */
	private int getDaysOfMonth(String yearMonth){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, Integer.parseInt(yearMonth.substring(0, 4)));
		calendar.set(Calendar.MONTH, Integer.parseInt(yearMonth.substring(4, 6))-1);
		calendar.set(Calendar.DATE, 1);
		int daysOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		return daysOfMonth;
	}
	
	/**
	 * 获取结算日期集合
	 * 
	 * @param billMonth 账单年月
	 * @return
	 */
	private List<String> getSettleDateList(String billMonth){
		Calendar calendar = Calendar.getInstance();
		String currentDate = DateTimesUtil.date8(calendar.getTime());
		int daysOfMonth = getDaysOfMonth(billMonth);
		List<String> settleDateList = new ArrayList<String>();
		String billMonthDay = billMonth + daysOfMonth;
		for(int i = 0 ; i<daysOfMonth; i++){
			String settleDate = addDays(billMonthDay, -i);
			if(settleDate.compareTo(currentDate)>0){
				continue;
			}
			settleDateList.add(settleDate);
		}
		
		return settleDateList;
	}
	
	/**
	 * 日期加减天数
	 * 
	 * @param dateStr 日期
	 * @param days 天数
	 * @return
	 */
	private String addDays(String dateStr, int days){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
		calendar.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(4, 6))-1);
		calendar.set(Calendar.DATE, Integer.parseInt(dateStr.substring(6, 8)));
		calendar.add(Calendar.DATE, days);
        return DateTimesUtil.date8(calendar.getTime());
	}
	
	/**
	 * 文件路径集合
	 * @param merId 主商户号
	 * @param settleDateList 结算日期
	 * @return
	 * @throws ParseException
	 */
	private List<String> getBatchFilePath(String merId, List<String> settleDateList) throws ParseException{
		String excelPath = TimePathUtil.getTimePathWithXls(settleDateList.get(0), TimePathUtil.File.SETTLE);
		logger.info("日结算文件路径 excelPath ================ " + excelPath);
		List<String> fileNameList = new ArrayList<String>();
		for (int i = 0; i < settleDateList.size(); i++) {//对日期进行循环
			//过滤同时含有主商户号和日期的文件名
			SettleDirFilter settleDirFilter = new SettleDirFilter(merId, settleDateList.get(i));
			//获取文件列表
			String newPath = excelPath.replace(settleDateList.get(0), settleDateList.get(i));//文件存储路径
			File file = new File(newPath);
			String[] names = file.list(settleDirFilter);//路径下所有文件
			if(names != null){
				for (String name : names) {//遍历文件名，拼接路径和文件名
					String pathName = newPath + name;//拼接文件存储路径和文件名
					fileNameList.add(pathName);
				}
			}
		}
		return fileNameList;
	}
}
